'''
Created on 05.06.2013

@author: Besitzer, teilweise WebSocketServer von Max
'''
from libavg import avg,AVGApp
import sys,thread, threading
 
from twisted.internet import reactor
from twisted.python import log
 
from autobahn.websocket import WebSocketServerFactory, \
                               WebSocketServerProtocol, \
                               listenWS

###THIS CLASS SIMPLY HOLDS THE CONNECTED CLIENT IPS####
class IPStorage():
    def __init__(self):
        self._ipList=dict({})
        self.__lock = threading.Lock()
        self.__maxPlayer = threading.Semaphore(4)
        
    def addNewClient(self,ip,connection): ##adds a new Client to the Dictionary
        global isUser,noUser
        self.__maxPlayer.acquire()
        self.__lock.acquire()
        self._ipList[ip]=connection 
        if(len(self._ipList) == 1):
            Lobby.noUser.clear()
            Lobby.isUser.set()
        self.__lock.release()
    
    def dropConnection(self,ip):##removes Connection out of Dict
        global isUser,noUser
        self.__lock.acquire()
        del self._ipList[ip]
        self.__maxPlayer.release()
        if(len(self._ipList) == 0):
            Lobby.isUser.clear()
            Lobby.noUser.set()
        self.__lock.release()
        
    def getAllCurrentConnections(self):#returns all currently active Connections
        return self._ipList
    
    def getNumberOfConnections(self):
        return len(self._ipList)
    
    def getConnectionForIp(self,ip):##returns a Connection to a Client with a certain IP
        return self._ipList[ip]
    
    def updateAll(self,msg): #sends Message to all connected Clients
        for key in self._ipList:
            self._ipList[key].sendMessage(msg)
        

###WEBSOCKETPROTOCOL USED FOR COMMUNICATION####
class EchoServerProtocol(WebSocketServerProtocol):

    def onClose(self,wasClean,code,reason):
        print "Client left"
        Lobby.ips.dropConnection(self.peer.host) ##Drop Connection out of IPStorage when Client disconnects
        Lobby.ips.updateAll("Client with IP "+self.peer.host+" has disconnected")#Update all
        
    def onOpen(self):
        Lobby.ips.addNewClient(self.peer.host, self) ##adds current Connection and Client IP to the Storage
        Lobby.ips.updateAll("New Client with IP "+self.peer.host+" has joined")
              
    def onMessage(self, msg, binary):
        print "sending echo:", msg ##print incoming message
        self.sendMessage("Received: "+msg, binary)##send back message to initiating client
        
        
###Lobby###
class Lobby(object):
    
    def __init__(self, event):
        self.isUser = threading.Event()##laed den LobbyScreen sobald ein User da is
        self.noUser = threading.Event()##laed den HomeScreen sobald kein User mehr da is
        self.ips=IPStorage()
        thread.start_new_thread(self.initializeWebSocket, ()) ##start the WebSocket in new Thread
        print "test"
        event.set()
        
    def getIps(self):
        return self.ips
        
    def initializeWebSocket(self):
        log.startLogging(sys.stdout)##Create a logfile (not necessary)
        self.factory = WebSocketServerFactory("ws://localhost:9000", debug = False)
        self.factory.protocol = EchoServerProtocol ##assign our Protocol to send/receive Messages
        listenWS(self.factory)
        reactor.run(installSignalHandlers=0)#@UndefinedVariable##"installSignalHandlers=0" Necessary for Multithreading
        
    def getLobbyScreen(self,size,parent):
        container = avg.DivNode(size=size, parent=parent)
        self.__rect1 = avg.RectNode(pos=(0,0),size=size,  fillopacity=1,
                                     fillcolor="FFFFFF",  color="FFFFFF", parent=container)
        

    
    